package com.desire.fiilter;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 从前端检查jwt令牌是否无效
 */
public class JwtFilter extends GenericFilterBean {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //将servletRequest和servletResponse更改为HttpServletRequest和HttpServletResponse
        final HttpServletRequest request = (HttpServletRequest) servletRequest;
        final HttpServletResponse response = (HttpServletResponse) servletResponse;

        //从Http请求获取授权
        final String authHeader = request.getHeader("authorization");

        //如果Http请求为OPTIONS，则只需返回状态码200
        //在这段代码中是HttpServletResponse.SC_OK
        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            filterChain.doFilter(request, response);
        }
        //除OPTIONS外，其他请求应由JWT检查
        else {
            //检查授权，检查令牌是否由“ Bearer”启动
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                throw new ServletException("Missing or invalid Authorization header");
            }

            //然后从授权中获取JWT令牌
            final String token = authHeader.substring(7);

            try {
                //使用JWT解析器通过“ secretkey”密钥检查签名是否有效
                final Claims claims = Jwts.parser().setSigningKey("secretkey").parseClaimsJws(token).getBody();
                //将声明添加到请求标头
                request.setAttribute("claims", claims);
            } catch (final SignatureException e) {
                throw new ServletException("Invalid token");
            }

            filterChain.doFilter(request, response);
        }
    }
}
